﻿#include "BrowserTableHandlerSubsystemPlate.h"
#include "OperatorsInterface/OperAbstractSubsystem.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSEAModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractSEASubSys.h"
#include "FITK_Component/FITKAcousticsModel/FITKSEASubSysShellPlate.h"
#include "FITK_Component/FITKAcousticsModel/FITKSEASubSysGeoProp.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsNCT.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyRibbed.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyRibInfo.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsMaterial.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyUniform.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyGeneralLaminate.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyGeneralLaminateIsoLayer.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsPhysicsProp.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsSpectraManager.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyBeam.h"

namespace GUI
{
    void BrowserTableHandlerSubsystemPlate::updateTable()
    {
        if (_tableWidget == nullptr) return;
        _tableWidget->clear();
        _tableWidget->setColumnCount(0);
        _tableWidget->setRowCount(0);

        //设置表头
        QStringList headerLabels;
        headerLabels << tr("Name") << tr("Physical Properties") << tr("Flexural DLF")
            << tr("Area[m2]") << tr("Thickness[m]") << tr("Perimeter[m]") << tr("Mass[kg]") 
            << tr("Treatment Face +Z") << tr("Treatment Face -Z")
             << tr("Notes");
        _tableWidget->setColumnCount(headerLabels.size());
        _tableWidget->setHorizontalHeaderLabels(headerLabels);
        //更新表格
        this->updateData();
    }

    void BrowserTableHandlerSubsystemPlate::updateData()
    {
        if (_tableWidget == nullptr) return;
        if (_seaMgr == nullptr || _propMgr == nullptr)return;

        QList<Acoustics::FITKAbstractSEASubSys*> list = _seaMgr->getSubSysByType(
            Acoustics::FITKAbstractSEASubSys::SEAFlatPlate);

        updateLine(&list);
        _tableWidget->autoResizeCellWidth();
        _tableWidget->setTableItemEditable(false);
    }

    EventOper::OperAbstractSubsystem * BrowserTableHandlerSubsystemPlate::getSubsystemOper()
    {
        //从操作器仓库获取
        return Core::FITKOperatorRepo::getInstance()->
            getOperatorT<EventOper::OperAbstractSubsystem>("OperSubsystemPlate");
    }

    bool BrowserTableHandlerSubsystemPlate::enableAttriSet()
    {
        QList<QTableWidgetItem*> selectItems = this->getSelectItems();
        if (selectItems.size() < 2) return false;

        QTableWidgetItem* item = selectItems.at(0);
        if (item == nullptr) return false;
        //名称列
        const int colIndex = item->column();
        //板材料，频谱，内外声学包种类
        if (!(colIndex==1 || colIndex==2||colIndex == 7 || colIndex == 8)) return false;

        return true;
    }

    int BrowserTableHandlerSubsystemPlate::getTitleColumnByName(QString name)
    {
        if (nullptr == _tableWidget)return -1;
        for (int col = 0; col < _tableWidget->columnCount(); ++col){
            QString headerText = _tableWidget->model()->headerData(col, Qt::Horizontal).toString();  // 获取水平表头文本
            if (name == headerText)return col;
        }
        return -1;
    }

    void BrowserTableHandlerSubsystemPlate::updateLine(QList<Acoustics::FITKAbstractSEASubSys*> *list)
    {
        //物理属性数量
        if (!list) return;
        const int n = list->size();
        _tableWidget->setRowCount(n);
        for (int i = 0; i < n; ++i)
        {
            //转换为 板子系统
            Acoustics::FITKAbstractSEASubSysShell* sea = dynamic_cast<Acoustics::FITKAbstractSEASubSysShell*>(list->at(i));
            if (sea == nullptr) continue;
            //获取几何属性
            Acoustics::FITKSEASubSysGeoProp* geoProp = sea->getGeoProp();
            if (!geoProp)continue;
            double area = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Area);
            double perimeter = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Circumference);
            double r1 = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::RadiusR1);
            double r2 = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::RadiusR2);
            Acoustics::FITKAcousticsAbsPhysicsProp* phyProp = _propMgr->getDataByID(sea->getPropSectionID());
            if (!phyProp)continue;
            double thickness = 0;
            double mass = 0;
            Acoustics::FITKAcousticsAbsPhysicsProp::AcousticsPhyscisPropType type = phyProp->getPhysicsPropType();
            if (type == Acoustics::FITKAcousticsAbsPhysicsProp::AcousticsPhyscisPropType::APPUniformPlat) {
                Acoustics::FITKPhyscisPropertyUniform* uniformPhyProp = dynamic_cast<Acoustics::FITKPhyscisPropertyUniform*>(phyProp);
                if (!uniformPhyProp)continue;
                Acoustics::FITKAcousticsAbsMaterial* materialData = uniformPhyProp->getMaterial();
                if (!materialData)continue;
                thickness = uniformPhyProp->getThickness();
                mass = thickness * area * materialData->getDensity();
            }
            else if (type == Acoustics::FITKAcousticsAbsPhysicsProp::AcousticsPhyscisPropType::APPGeneralLaminatePhysicalProperty) {
                Acoustics::FITKPhyscisPropertyGeneralLaminate* generalLaminatePhyProp = dynamic_cast<Acoustics::FITKPhyscisPropertyGeneralLaminate*>(phyProp);
                if (!generalLaminatePhyProp)continue;
                double unitMass = 0.0;
                for (int i = 0; i < generalLaminatePhyProp->getDataCount(); ++i) {
                    Acoustics::FITKPhyscisPropertyGeneralLaminateIsoLayer* singlyLayerDate = generalLaminatePhyProp->getDataByIndex(i);
                    if (!singlyLayerDate)continue;
                    Acoustics::FITKAcousticsAbsMaterial* materialData = singlyLayerDate->getMaterialObj();
                    if (!materialData)continue;
                    unitMass += singlyLayerDate->getThickness() * materialData->getDensity();
                    thickness += singlyLayerDate->getThickness();
                }
                mass = unitMass * area;
            }
            else if (type == Acoustics::FITKAcousticsAbsPhysicsProp::AcousticsPhyscisPropType::APPRibbedphysicalProperty) {
                Acoustics::FITKPhyscisPropertyRibbed* ribbedPhyProp = dynamic_cast<Acoustics::FITKPhyscisPropertyRibbed*>(phyProp);
                if (!ribbedPhyProp)return;
                //获取基板属性，筋
                Acoustics::FITKAcousticsAbsPhysicsProp* skinData = ribbedPhyProp->getSkinPropObj();
                Acoustics::FITKPhyscisPropertyRibInfo* rib1Data = ribbedPhyProp->getDri1RibInfo();
                Acoustics::FITKPhyscisPropertyRibInfo* rib2Data = ribbedPhyProp->getDri2RibInfo();
                if (!skinData || !rib1Data)return;
                if (skinData->getPhysicsPropType() == Acoustics::FITKAcousticsAbsPhysicsProp::APPUniformPlat) {
                    Acoustics::FITKPhyscisPropertyUniform* uniformPhyProp = dynamic_cast<Acoustics::FITKPhyscisPropertyUniform*>(skinData);
                    if (!uniformPhyProp)continue;
                    Acoustics::FITKAcousticsAbsMaterial* materialData = uniformPhyProp->getMaterial();
                    if (!materialData)continue;
                    thickness = uniformPhyProp->getThickness();
                    //基板质量
                    mass = thickness * area * materialData->getDensity();
                }
                else if (skinData->getPhysicsPropType() == Acoustics::FITKAcousticsAbsPhysicsProp::APPGeneralLaminatePhysicalProperty) {
                    Acoustics::FITKPhyscisPropertyGeneralLaminate* generalLaminatePhyProp = dynamic_cast<Acoustics::FITKPhyscisPropertyGeneralLaminate*>(skinData);
                    if (!generalLaminatePhyProp)continue;
                    double unitMass = 0.0;
                    for (int i = 0; i < generalLaminatePhyProp->getDataCount(); ++i) {
                        Acoustics::FITKPhyscisPropertyGeneralLaminateIsoLayer* singlyLayerDate = generalLaminatePhyProp->getDataByIndex(i);
                        if (!singlyLayerDate)continue;
                        Acoustics::FITKAcousticsAbsMaterial* materialData = singlyLayerDate->getMaterialObj();
                        if (!materialData)continue;
                        unitMass += singlyLayerDate->getThickness() * materialData->getDensity();
                        thickness += singlyLayerDate->getThickness();
                    }
                    //基板质量
                    mass = unitMass * area;
                }
                Acoustics::FITKPhyscisPropertyBeam* rib1BeamData = dynamic_cast<Acoustics::FITKPhyscisPropertyBeam*>(rib1Data->getBeamPropObj());
                if (!rib1BeamData) continue;
                Acoustics::FITKAcousticsAbsMaterial* rib1MaterialData = rib1BeamData->getMaterial();
                if (!rib1MaterialData)continue;
                double rib1Mass = rib1BeamData->getCrossSectionArea() * rib1MaterialData->getDensity() * area / rib1Data->getSpacing();
                //基板+第一条筋的质量
                mass = mass + rib1Mass;
                if (rib2Data) {
                    Acoustics::FITKPhyscisPropertyBeam* rib2BeamData = dynamic_cast<Acoustics::FITKPhyscisPropertyBeam*>(rib2Data->getBeamPropObj());
                    if (rib2BeamData) {
                        Acoustics::FITKAcousticsAbsMaterial* rib2MaterialData = rib2BeamData->getMaterial();
                        if (rib2MaterialData) {
                            double rib2Mass = rib2BeamData->getCrossSectionArea() * rib2MaterialData->getDensity() * area / rib2Data->getSpacing();
                            //基板+第一条筋+第二条筋 的质量
                            mass = mass + rib2Mass;
                        }
                    }
                }
            }
            //数据ID
            const int id = sea->getDataObjectID();
            //填充表格，用type表示ID
            _tableWidget->setItem(i, 0, new QTableWidgetItem(sea->getDataObjectName(), id));
            _tableWidget->setItem(i, 1, new QTableWidgetItem(phyProp->getDataObjectName(), id));
            _tableWidget->setItem(i, 2, new QTableWidgetItem(sea->getFlexureSpectra()->getDataObjectName(), id));
            _tableWidget->setItem(i, 3, new QTableWidgetItem(QString::number(area), id));
            _tableWidget->setItem(i, 4, new QTableWidgetItem(QString::number(thickness), id));
            _tableWidget->setItem(i, 5, new QTableWidgetItem(QString::number(perimeter), id));
            _tableWidget->setItem(i, 6, new QTableWidgetItem(QString::number(mass), id));
            QString outsideNCT = "None";
            if (sea->getOutsideNCT()) outsideNCT = sea->getOutsideNCT()->getDataObjectName();
            _tableWidget->setItem(i, 7, new QTableWidgetItem(outsideNCT, id));
            QString insideNCT = "None";
            if (sea->getInsideNCT()) insideNCT = sea->getInsideNCT()->getDataObjectName();
            _tableWidget->setItem(i, 8, new QTableWidgetItem(insideNCT, id));
            int Column1 = getTitleColumnByName(tr("Radius R1[m]"));
            if (Column1 != -1) _tableWidget->setItem(i, Column1, new QTableWidgetItem(QString::number(r1), id));
            int Column2 = getTitleColumnByName(tr("Radius R2[m]"));
            if (Column2 != -1) _tableWidget->setItem(i, Column2, new QTableWidgetItem(QString::number(r2), id));
            //_tableWidget->setItem(i,getTitleColumnByName(tr("Notes")) , new QTableWidgetItem(sea->getDescribe(), id));
        }
    }
}